package mock.servicesdirectory.contacts.business.businessimpl;

import java.util.ArrayList;
import java.util.List;

import mock.servicesdirectory.common.conts.ContactModelConts;
import mock.servicesdirectory.common.entities.Contact;
import mock.servicesdirectory.contacts.business.businessinterface.ContactBo;
import mock.servicesdirectory.contacts.dao.daointerface.ContactDao;
import mock.servicesdirectory.contacts.web.model.ContactModel;

public class ContactBoImpl implements ContactBo {
	private ContactDao contactDao;

	private List<ContactModel> contactModels;

	/**
	 * @param contactDao
	 *            the contactDao to set
	 */
	public void setContactDao(ContactDao contactDao) {
		this.contactDao = contactDao;
	}

	/**
	 * @return the contactDao
	 */
	public ContactDao getContactDao() {
		return contactDao;
	}

	/**
	 * Method used to initial database by call to Dao object If list contact
	 * that created before, method does nothing
	 */
	@Override
	public void initContacts() {
		contactModels = new ArrayList<ContactModel>();
		List<Contact> contacts = contactDao.getContacts();
		ContactModel item;
		for (Contact c : contacts) {
			item = new ContactModel();
			item.setContactId(c.getContactId());
			item.setFirstName(c.getFirstName());
			item.setSurName(c.getSurName());
			item.setContactName(c.getFirstName() + " " + c.getSurName());
			item.setMobilePhone(c.getMobilePhone());
			item.setEmail(c.getEmail());
			item.setContactType(c.getContactType());
			if (c.isIsActive()) {
				item.setIsActive(ContactModelConts.IS_ACTIVE_TRUE);
			} else {
				item.setIsActive(ContactModelConts.IS_ACTIVE_FALSE);
			}
			contactModels.add(item);
		}
	}

	/**
	 * Method used to get list contact from database with filter
	 */
	@Override
	public List<ContactModel> getContacts(String firstName, String surName,
			boolean isActive) {
		List<ContactModel> contactModels = new ArrayList<ContactModel>();
		List<Contact> contacts;

		boolean isFilterFirstName = firstName != null && !firstName.isEmpty();
		boolean isFilterSurName = surName != null && !firstName.isEmpty();

		if (isActive) {
			if (isFilterFirstName && isFilterSurName) {
				contacts = contactDao.getContacts(firstName, surName, isActive);
			} else if (isFilterFirstName) {
				contacts = contactDao.getContactsFilterFirstName(firstName,
						isActive);
			} else if (isFilterSurName) {
				contacts = contactDao.getContactsFilterSurName(surName,
						isActive);
			} else {
				contacts = contactDao.getContacts(isActive);
			}
		} else {
			if (isFilterFirstName && isFilterSurName) {
				contacts = contactDao.getContacts(firstName, surName);
			} else if (isFilterFirstName) {
				contacts = contactDao.getContactsFilterFirstName(firstName);
			} else if (isFilterSurName) {
				contacts = contactDao.getContactsFilterSurName(surName);
			} else {
				contacts = contactDao.getContacts();
			}
		}

		ContactModel item;
		for (Contact c : contacts) {
			item = new ContactModel();
			item.setContactId(c.getContactId());
			item.setFirstName(c.getFirstName());
			item.setSurName(c.getSurName());
			item.setContactName(c.getFirstName() + " " + c.getSurName());
			item.setMobilePhone(c.getMobilePhone());
			item.setEmail(c.getEmail());
			item.setContactType(c.getContactType());
			if (c.isIsActive()) {
				item.setIsActive(ContactModelConts.IS_ACTIVE_TRUE);
			} else {
				item.setIsActive(ContactModelConts.IS_ACTIVE_FALSE);
			}
			contactModels.add(item);
		}

		return contactModels;
	}

	/**
	 * Method used to filter contact by first name, surname, isactive from list
	 * contact that retrieved from database before
	 */
	@Override
	public List<ContactModel> getContactWithFilter(String firstName,
			String surName, boolean isActive) {
		List<ContactModel> result = new ArrayList<ContactModel>();

		boolean isFilterFirstName = (firstName != null && !firstName.isEmpty());
		boolean isFilterSurName = (surName != null && !firstName.isEmpty());

		for (ContactModel contact : contactModels) {
			if (isActive) {
				if (isFilterFirstName && isFilterSurName) {
					if (containFirstName(contact, firstName)
							&& containSurName(contact, surName)
							&& isActiveContact(contact)) {
						result.add(contact);
					}
				} else if (isFilterFirstName) {
					if (containFirstName(contact, firstName)
							&& isActiveContact(contact)) {
						result.add(contact);
					}
				} else if (isFilterSurName) {
					if (containSurName(contact, surName)
							&& isActiveContact(contact)) {
						result.add(contact);
					}
				} else {
					if (isActiveContact(contact)) {
						result.add(contact);
					}
				}
			} else {
				if (isFilterFirstName && isFilterSurName) {
					if (containFirstName(contact, firstName)
							&& containSurName(contact, surName)) {
						result.add(contact);
					}
				} else if (isFilterFirstName) {
					if (containFirstName(contact, firstName)) {
						result.add(contact);
					}
				} else if (isFilterSurName) {
					if (containSurName(contact, surName)) {
						result.add(contact);
					}
				} else {
					result.add(contact);
				}
			}
		}
		return result;
	}

	/**
	 * Method used to check a contact has firstname begin with special string
	 * 
	 * @param contact
	 * @param firstName
	 * @return
	 */
	private boolean containFirstName(ContactModel contact, String firstName) {
		if (contact.getFirstName().toLowerCase().trim()
				.startsWith(firstName.toLowerCase())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Method used to check a contat has surname begin with special string
	 * 
	 * @param contact
	 * @param surName
	 * @return
	 */
	private boolean containSurName(ContactModel contact, String surName) {
		if (contact.getSurName().toLowerCase().trim()
				.startsWith(surName.toLowerCase())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Method used to check a conctact is active or not
	 * 
	 * @param contact
	 * @return
	 */
	private boolean isActiveContact(ContactModel contact) {
		if (contact.getIsActive().trim()
				.equals(ContactModelConts.IS_ACTIVE_TRUE)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Method used to filter contact by first name from list contact that pass
	 * by parameter
	 */
	@Override
	public List<ContactModel> getContactWithFilterFirstName(
			List<ContactModel> contacts, String firstName) {
		List<ContactModel> result = new ArrayList<ContactModel>();
		for (ContactModel contact : contacts) {
			if (contact.getFirstName().trim().startsWith(firstName)) {
				result.add(contact);
			}
		}
		return result;
	}

	/**
	 * Method used to filter contact by surname from list contact that pass by
	 * parameter
	 */
	@Override
	public List<ContactModel> getContactWithFilterSurName(
			List<ContactModel> contacts, String surName) {
		List<ContactModel> result = new ArrayList<ContactModel>();
		for (ContactModel contact : contacts) {
			if (contact.getSurName().trim().startsWith(surName)) {
				result.add(contact);
			}
		}
		return result;
	}

	/**
	 * @param contactModels
	 *            the contactModels to set
	 */
	@Override
	public void setContactModels(List<ContactModel> contactModels) {
		this.contactModels = contactModels;
	}

	/**
	 * @return the contactModels
	 */
	@Override
	public List<ContactModel> getContactModels() {
		return contactModels;
	}

	@Override
	public List<ContactModel> findContact(List<ContactModel> contactModels,
			int from, int to) {
		return contactModels.subList(from, to);
	}

	@Override
	public int countContact() {
		if (contactModels == null) {
			return 0;
		} else {
			return contactModels.size();
		}
	}

	/**
	 * Method used to save or update a contact into database
	 */
	@Override
	public boolean saveOrupdateContact(Contact contact) {
		return contactDao.saveOrUpdateContact(contact);
	}

	/**
	 * Method used to get a contact correspose with contactID through dao object
	 * 
	 * @param contactID
	 * @return
	 */
	@Override
	public Contact getContact(int contactID) {
		return contactDao.getContact(contactID);
	}
}